﻿/*========================== 
 * @author 郑金泉
 * @desc 图形处理实用工具
 * ========================= */
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Obsidian.Utils
{
    public class ImageUtil
    {
        /// <summary>
        /// 从路径获得图像对象
        /// </summary>
        /// <param name="fileName">图片物理路径</param>
        /// <returns>Bitmap对象</returns>
        public static Bitmap GetBitmap(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return null;
            Bitmap bitmap = null;
            try
            {
                bitmap = (Bitmap)Bitmap.FromFile(fileName);
                return bitmap;
            }
            catch (Exception e) { return null; }
        }

        /// <summary>
        /// 从文件流获得图像对象
        /// </summary>
        /// <param name="fileStream">文件流</param>
        /// <returns>Bitmap对象</returns>
        public static Bitmap GetBitmap(Stream fileStream)
        {
            Bitmap bitmap = null;
            try
            {
                bitmap = (Bitmap)Bitmap.FromStream(fileStream);
                return bitmap;
            }
            catch (ArgumentException) { return null; }
        }


        /// <summary>
        /// 等比例缩放图片
        /// </summary>
        /// <param name="fileName">原图片路径</param>
        /// <param name="maxWidth">最大宽度</param>
        /// <param name="maxHeight">最大高度</param>
        /// <returns></returns>
        public static Bitmap RatioImage(string fileName, int maxWidth, int maxHeight)
        {
            Bitmap bitmap = GetBitmap(fileName);
            if (bitmap == null)
                return null;
            else
                return RatioImage(bitmap, maxWidth, maxHeight);
        }

        /// <summary>
        /// 等比例缩放图片
        /// </summary>
        /// <param name="bitmap">原图片</param>
        /// <param name="maxWidth">最大宽度</param>
        /// <param name="maxHeight">最大高度</param>
        /// <returns></returns>
        public static Bitmap RatioImage(Bitmap bitmap, int maxWidth, int maxHeight)
        {
            int h = bitmap.Height;
            int w = bitmap.Width;
            if (h > maxHeight)
            {
                w = (int)(w * ((double)maxHeight / h));
                h = maxHeight;
            }
            if (w > maxWidth)
            {
                h = (int)(h * ((double)maxWidth / w));
                w = maxWidth;
            }

            try
            {
                Bitmap newImg = new Bitmap(w, h);
                Graphics g = Graphics.FromImage(newImg);//构建newImg的绘图对象
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;//设置变换图象时的插补模式
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置图片的呈现质量
                g.Clear(Color.Transparent);//以透明色填充
                g.DrawImage(bitmap, new Rectangle(0, 0, w, h), new Rectangle(0, 0, bitmap.Width, bitmap.Height), GraphicsUnit.Pixel);//绘制新图片
                g.Dispose();
                return newImg;
            }
            catch { return null; }
        }


        /// <summary>
        /// 创建验证码图片
        /// </summary>
        /// <param name="verifyCode">验证码</param>
        /// <returns>验证码图片</returns>
        public static Bitmap CreateVerifyCodeBitmap(string verifyCode)
        {
            int randAngle = 45; //随机转动角度  
            int mapwidth = (int)(verifyCode.Length * 23);
            Bitmap map = new Bitmap(mapwidth, 28);//创建图片背景  
            Graphics g = Graphics.FromImage(map);
            g.Clear(Color.AliceBlue);//清除画面，填充背景  
            g.DrawRectangle(new Pen(Color.Black, 0), 0, 0, map.Width - 1, map.Height - 1);//画一个边框  
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//模式  
            Random rand = new Random();
            //背景噪点生成  
            Pen JimPen = new Pen(Color.LightGray, 0);
            for (int i = 0; i < 50; i++)
            {
                int x = rand.Next(0, map.Width);
                int y = rand.Next(0, map.Height);
                g.DrawRectangle(JimPen, x, y, 1, 1);
            }
            //验证码旋转，防止机器识别  
            char[] chars = verifyCode.ToCharArray();//拆散字符串成单字符数组  
            //文字距中  
            StringFormat format = new StringFormat(StringFormatFlags.NoClip);
            format.Alignment = StringAlignment.Center;
            format.LineAlignment = StringAlignment.Center;
            //定义颜色  
            Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
            //定义字体  
            string[] font = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
            for (int i = 0; i < chars.Length; i++)
            {
                int cindex = rand.Next(7);
                int findex = rand.Next(5);
                Font f = new System.Drawing.Font(font[findex], 13, System.Drawing.FontStyle.Bold);//字体样式(参数2为字体大小)  
                Brush b = new System.Drawing.SolidBrush(c[cindex]);
                Point dot = new Point(16, 16);
                //g.DrawString(dot.X.ToString(),fontstyle,new SolidBrush(Color.Jim),10,150);//测试X坐标显示间距的  
                float angle = rand.Next(-randAngle, randAngle);//转动的度数  
                g.TranslateTransform(dot.X, dot.Y);//移动光标到指定位置  
                g.RotateTransform(angle);
                g.DrawString(chars[i].ToString(), f, b, 1, 1, format);
                //g.DrawString(chars[i].ToString(),fontstyle,new SolidBrush(Color.Blue),1,1,format);  
                g.RotateTransform(-angle);//转回去  
                g.TranslateTransform(2, -dot.Y);//移动光标到指定位置  
            }
            //g.DrawString(verifyCode,fontstyle,new SolidBrush(Color.Blue),2,2); //标准随机码 
            g.Dispose();
            return map;
        }

        /// <summary>
        /// Image转成byte[]
        /// </summary>
        /// <param name="imageIn"></param>
        /// <returns></returns>
        public static byte[] ImageToByteArray(System.Drawing.Image imageIn) 
        {
            MemoryStream ms = new MemoryStream();
            imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            return ms.ToArray();
        }

        public static Image ToImage(byte[] bytes)
        {
            MemoryStream ms = new MemoryStream(bytes);
            Image img = Image.FromStream(ms, true);
            return img; 
        }

    }
}
